package com.th.apicenter.oppo.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.th.apicenter.deduct.entity.ThDeduct;
import com.th.apicenter.config.ApplicationProperties;
import com.th.apicenter.mapper.ThDeductMapper;
import com.th.apicenter.mapper.ThOPPODataMapper;
import com.th.apicenter.oppo.dto.OPPOPassBackDTO;
import com.th.apicenter.oppo.dto.ThOPPONumDTO;
import com.th.apicenter.oppo.entity.ThOppoData;
import com.th.apicenter.tools.ThTools;
import com.th.apicenter.tools.Md5Tools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

@Service
@Slf4j
public class OPPOService {

    @Resource
    private ThOPPODataMapper thOPPODataMapper;

    @Resource
    private ThDeductMapper thDeductMapper;

    @Resource
    private ApplicationProperties applicationProperties;

    /**
     * 20250428 oppo只做假回传
     *
     * @param thOppoData
     */
    public String receive(ThOppoData thOppoData) {
        //判断是否回传
        ThDeduct thDeduct = thDeductMapper.selectOne(new QueryWrapper<ThDeduct>()
                .eq("type", "oppo")
                .eq("account_id", thOppoData.getAccountId()));
        thOppoData.setCreateTime(new Date());
        thOPPODataMapper.insert(thOppoData);
        log.info("oppo检测接收到的数据：{}", thOppoData);
        if (null != thDeduct && thDeduct.getIsTrue() == 1) {
            Date currentTime = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String date = formatter.format(currentTime);
            String startTime = date + " 00:00:00";
            String endTime = date + " 23:59:59";
            ThOPPONumDTO thOPPONumDTO = thOPPODataMapper.queryNumByDate(thOppoData.getAccountId(),startTime, endTime);
            if (thOPPONumDTO.getPassbackNum() >= 1) {
                // 计算回调比例（passbackNum/total）
                BigDecimal x = new BigDecimal(thOPPONumDTO.getPassbackNum()).divide(new BigDecimal(thOPPONumDTO.getTotal()), 2, RoundingMode.CEILING);
                // 获取配置的扣量阈值（百分比转换为小数）
                BigDecimal percent = new BigDecimal(thDeduct.getPercent()).divide(new BigDecimal(100), 2, RoundingMode.CEILING);
                // 决策条件：(1 - 回调比例) < 配置阈值 → 触发扣量
                BigDecimal subtract = new BigDecimal(1).subtract(x);
                // 核心扣量逻辑：当 (1 - 回调比例) < 阈值时触发扣量
                if (percent.doubleValue() != 0 && subtract.compareTo(percent) < 0) {
                    log.info("需要扣量，不做操作!");
                    thOppoData.setIsDeduct(1);
                } else {
                    passBackOppo(thOppoData);
                    thOppoData.setIsOppoPassback(1);
                }
            } else {
                passBackOppo(thOppoData);
                thOppoData.setIsOppoPassback(1);
            }
            thOppoData.setUpdateTime(new Date());
            thOPPODataMapper.updateById(thOppoData);
        }
        return "数据已接收";
    }

    public void passBackOppo(ThOppoData thOppoData) {
        //回传给oppo
        OPPOPassBackDTO oppoPassBackDTO = new OPPOPassBackDTO();
        try {

            if (!ThTools.isNull(thOppoData.getImei())) {
                oppoPassBackDTO.setImei(encrypt(thOppoData.getImei(), applicationProperties.getOppo().getBase64Key()));
            }
            if (null == oppoPassBackDTO.getImei() && !ThTools.isNull(thOppoData.getOaid())) {
                oppoPassBackDTO.setOuId(encrypt(thOppoData.getOaid(), applicationProperties.getOppo().getBase64Key()));
            }
            oppoPassBackDTO.setRequestId(thOppoData.getReqId());
            oppoPassBackDTO.setTimestamp(System.currentTimeMillis());
            oppoPassBackDTO.setPkg("com.kuaishou.nebula");
            oppoPassBackDTO.setDataType(6);
            oppoPassBackDTO.setChannel(1);
            oppoPassBackDTO.setType(0);
            oppoPassBackDTO.setAscribeType(1);
            oppoPassBackDTO.setAdId(Long.valueOf(thOppoData.getAdId()));

            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(oppoPassBackDTO);

            String signature = Md5Tools.md5(jsonObject.toJSONString() + oppoPassBackDTO.getTimestamp() + applicationProperties.getOppo().getSalt()).toLowerCase();
            log.info("上报oppo的signature：{}", signature);
            log.info("上报oppo的jsonObject：{}", jsonObject);
            String result = sendOPPOHttpPost(applicationProperties.getOppo().getUploadUrl(), signature, oppoPassBackDTO.getTimestamp(), jsonObject);
            log.info("oppo回传的接口返回：{}", result);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public static String encrypt(String plainText, String base64Key) throws Exception {
        // 1. 解码Base64密钥
        byte[] keyBytes = Base64.getDecoder().decode(base64Key);

        // 密钥长度校验
        if (keyBytes.length != 16 && keyBytes.length != 24 && keyBytes.length != 32) {
            throw new IllegalArgumentException("Key must be 16/24/32 bytes for AES-128/192/256");
        }

        // 2. 创建AES/ECB/PKCS5Padding加密器（PKCS5Padding对应C#的PKCS7）
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        // 3. 加密数据（UTF-8编码）
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

        // 4. 返回Base64字符串（自动去除换行符）
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public String sendOPPOHttpPost(String urlx, String signature, long timestamp, JSONObject jsonObject) {
        String result = "";
        log.info("urlx：{}", urlx);
        log.info("signature：{}", signature);
        log.info("timestamp：{}", timestamp);
        log.info("jsonObject：{}", jsonObject);
        try {

            URL url = new URL(urlx);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true); // 允许写入请求体

            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            conn.setRequestProperty("timeStamp", String.valueOf(timestamp));
            conn.setRequestProperty("signature", signature);

            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
            }

            int responseCode = conn.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            if (responseCode == HttpURLConnection.HTTP_OK) {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                    StringBuilder response = new StringBuilder();
                    String responseLine;
                    while ((responseLine = br.readLine()) != null) {
                        response.append(responseLine.trim());
                    }
                    log.info("上报oppo回传后，返回的数据：{}", response);
                }
            } else {
                log.info("Request failed. Response Code:{}", responseCode);
            }

            conn.disconnect();

        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

}

